package com.wangijun.yuan.web.service;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.wangijun.yuan.web.base.CommonResult;
import com.wangijun.yuan.core.domain.UserAuth;
import com.wangijun.yuan.core.domain.UserInfo;
import com.wangijun.yuan.core.model.em.UserStatusEnum;
import com.wangijun.yuan.core.util.AesUtil;
import com.wangijun.yuan.web.model.dto.ChangeUserParam;
import com.wangijun.yuan.web.model.dto.UpdatePasswdParam;
import com.wangijun.yuan.web.model.vo.UserInfoVO;
import com.wangijun.yuan.web.util.YuanWebUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


/**
 * 功能描述: 个人中心服务
 *
 * @author wlf 2024/6/23 22:19
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PersonService {
    private final UserService userService;
    private final OperateInfoService operateInfoService;

    public UserInfoVO userInfo(Long id) {
        if (id == null) {
            throw new RuntimeException("用户ID为空");
        }
        UserInfoVO userVO = BeanUtil.copyProperties(userService.get(id), UserInfoVO.class);
        UserAuth userAuth = Db.lambdaQuery(UserAuth.class)
                .eq(UserAuth::getUserId, userVO.getId())
                .one();
        if (userAuth == null) {
            userVO.setHasPasswd(false);
        } else {
            userVO.setHasPasswd(StrUtil.isNotBlank(userAuth.getPasswd()));
        }
        userVO.setFollowFlag(operateInfoService.getFollowUserIds().contains(userVO.getId()));
        return userVO;
    }

    public void cancelUser() {
        Long loginId = StpUtil.getLoginIdAsLong();
        StpUtil.logout();
        // 更新用户为注销状态
        UserInfo userInfo = new UserInfo();
        userInfo.setId(loginId);
        userInfo.setUserStatus(UserStatusEnum.del);
        userService.changeById(userInfo);
        Db.lambdaUpdate(UserAuth.class)
                .eq(UserAuth::getUserId, loginId)
                .set(UserAuth::getPasswd, "")
                .set(UserAuth::getSalt, "")
                .update();
    }

    public void updatePasswd(UpdatePasswdParam param) {
        if (StrUtil.isBlank(param.getOldPasswd())) {
            CommonResult.error("旧密码不可为空");
        }
        checkPass(param);
        UserInfo userInfo = Db.getById(StpUtil.getLoginIdAsLong(), UserInfo.class);
        UserAuth userAuth = Db.lambdaQuery(UserAuth.class).eq(UserAuth::getUserId, userInfo.getId()).one();
        // 比较旧密码
        if (!AesUtil.dec(userAuth.getPasswd()).equals(userAuth.getSalt() + param.getOldPasswd())) {
            CommonResult.error("原密码不正确!");
        }
        // 校验完成，开始更新密码
        updatePass(userAuth.getId(), param.getNewPasswd());
    }

    /**
     * 功能描述: 校验密码
     *
     * @author wlf 2024/6/23 22:16
     */
    private void checkPass(UpdatePasswdParam param) {
        if (StrUtil.isBlank(param.getNewPasswd())) {
            CommonResult.error("新密码不可为空");
        }
        if (!param.getNewPasswd().equals(param.getNewPasswd2())) {
            CommonResult.error("两次输入的密码不一致请检查");
        }

        if (!YuanWebUtil.checkPd(param.getNewPasswd())) {
            CommonResult.error("密码只能为字母，数字，下划线");
        }
    }

    /**
     * 功能描述: 更新密码
     *
     * @author wlf 2024/6/23 22:25
     */
    private void updatePass(Long authId, String newPasswd) {
        UserAuth auth = new UserAuth();
        auth.setId(authId);
        auth.setSalt(RandomUtil.randomString(6));
        auth.setPasswd(AesUtil.enc(auth.getSalt() + newPasswd));
        Db.updateById(auth);
    }

    public void setPasswd(UpdatePasswdParam param) {
        checkPass(param);
        UserInfo userInfo = Db.getById(StpUtil.getLoginIdAsLong(), UserInfo.class);
        UserAuth userAuth = Db.lambdaQuery(UserAuth.class).eq(UserAuth::getUserId, userInfo.getId()).one();
        // 校验完成，开始更新密码
        updatePass(userAuth.getId(), param.getNewPasswd());
    }

    /**
     * 功能描述: 更新用户
     *
     * @author wlf 2024/6/25 22:44
     */
    @Transactional
    public void updateLoginUser(ChangeUserParam param) {
        try {
            UserInfo userInfo = BeanUtil.copyProperties(param, UserInfo.class);
            userInfo.setId(StpUtil.getLoginIdAsLong());
            userService.changeById(userInfo);
        } catch (Exception e) {
            log.error("更新用户出错", e);
            throw new RuntimeException(e.getMessage());
        }

    }

    /**
     * 功能描述: 修改头像
     *
     * @author wlf 2024/6/25 22:46
     */
    public void changeAvatar(String avatar) {
        userService.changeById(UserInfo.builder()
                .id(StpUtil.getLoginIdAsLong())
                .avatar(avatar).build());
    }
}
